package com.kingyea.mobilepolice.user.controller;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.kingyea.mobilepolice.dictionary.bean.Dictionary;
import com.kingyea.mobilepolice.dictionary.bean.DictionaryCondition;
import com.kingyea.mobilepolice.dictionary.service.DictionaryService;
import com.kingyea.mobilepolice.organization.bean.Organization;
import com.kingyea.mobilepolice.organization.bean.OrganizationCondition;
import com.kingyea.mobilepolice.organization.service.OrganizationService;
import com.kingyea.mobilepolice.security.SecurityUtils;
import com.kingyea.mobilepolice.system.Result;
import com.kingyea.mobilepolice.system.StateCode;
import com.kingyea.mobilepolice.system.aspect.NotResult;
import com.kingyea.mobilepolice.user.bean.User;
import com.kingyea.mobilepolice.user.bean.UserCondition;
import com.kingyea.mobilepolice.user.bean.UserVo;
import com.kingyea.mobilepolice.user.service.UserService;
import com.kingyea.mobilepolice.userorg.bean.UserOrgCondition;
import com.kingyea.mobilepolice.util.BasePage;
import com.kingyea.mobilepolice.util.ExceptionConditions;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author cxc
 * @version v1.0.0
 * @description This is a class
 * @date Created in 2018.04.08 15:04
 */

@RestController
@RequestMapping("/user")
public class UsersController {

    @Autowired
    private UserService userService;

    @Autowired
    private OrganizationService organizationService;

    @Autowired
    private DictionaryService dictionaryService;

    //    @PostMapping("/list")
    @RequestMapping(value = "/list", method = RequestMethod.POST)
    public Result<BasePage<UserVo>> getUserList(@RequestBody UserCondition condition) throws Exception {
        List<User> userList = userService.search(condition);
        HashSet<Integer> userJobIdSet = Sets.newHashSet();
        HashSet<String> userOrgSerialNoSet = Sets.newHashSet();
        List<UserVo> userVoList = userList.stream().map(user -> {
            Optional.ofNullable(user.getJobCategory()).filter(str -> !str.equals("")).ifPresent(str -> userJobIdSet.add(Integer.valueOf(str)));
            userOrgSerialNoSet.add(user.getOrgSerialNo());
            UserVo vo = new UserVo();
            BeanUtils.copyProperties(user, vo);
            return vo;
        }).collect(Collectors.toList());

        OrganizationCondition orgCondition = new OrganizationCondition();
        orgCondition.setPageAble(false);
        orgCondition.setOrgIds(Lists.newArrayList(userOrgSerialNoSet));
        List<Organization> orgList = organizationService.search(orgCondition);

        DictionaryCondition dicCondition = new DictionaryCondition();
        dicCondition.setPageAble(false);
        dicCondition.setDictionaryIds(Lists.newArrayList(userJobIdSet));
        List<Dictionary> dicJobList = dictionaryService.search(dicCondition);

        userVoList.stream().forEach(vo -> {
            orgList.stream().filter(org -> org.getOrgSerialNo().equals(vo.getOrgSerialNo())).findAny().ifPresent(org -> vo.setOrgName(org.getName()));
            dicJobList.stream().filter(job -> !StringUtils.isBlank(vo.getJobCategory()) && String.valueOf(job.getId()).equals(vo.getJobCategory())).peek(job -> System.out.println(JSON.toJSONString(job))).findAny().ifPresent(job -> vo.setJobTypeName(job.getName()));
        });

        BasePage<UserVo> voCondition = new BasePage<UserVo>();
        BeanUtils.copyProperties(condition, voCondition);
        voCondition.setList(userVoList);
        return new Result<>(voCondition);
    }

    @RequestMapping(value = "/myUserlist", method = RequestMethod.POST)
    public Object myUserList(@RequestBody UserCondition condition) throws Exception {
        if (!SecurityUtils.isAdmin()) {
            UserOrgCondition userOrgCondition = new UserOrgCondition();
            userOrgCondition.setPageAble(false);
            userOrgCondition.setUserSerialNo(SecurityUtils.getCurrentUser().getUserId());
            List<Organization> orgList = organizationService.search(userOrgCondition);

            condition.setOrgSerialNos(orgList.stream().map(Organization::getOrgSerialNo).collect(Collectors.toList()));
        }
        List<User> userList = userService.search(condition);

        //注入关联字段
        List<UserVo> userVoList = userList.stream().map(user -> {
            UserVo vo = new UserVo();
            BeanUtils.copyProperties(user, vo);
            return vo;
        }).collect(Collectors.toList());

        List<String> orgSerialNoList = userVoList.stream().map(UserVo::getOrgSerialNo).distinct().collect(Collectors.toList());
        List<String> userIdList = userVoList.stream().map(UserVo::getCreatedBy).distinct().collect(Collectors.toList());

        OrganizationCondition orgCondition = new OrganizationCondition();
        orgCondition.setPageAble(false);
        orgCondition.setOrgIds(orgSerialNoList);
        List<Organization> orgList = organizationService.search(orgCondition);

        UserCondition userCondition = new UserCondition();
        userCondition.setPageAble(false);
        userCondition.setUserIdList(userIdList);
        List<User> createUserList = userService.search(userCondition);

        userVoList.stream().forEach(userVo -> {
            //注入部门名称
            orgList.stream().filter(org -> org.getOrgSerialNo().equals(userVo.getOrgSerialNo())).findAny().ifPresent(userOrg -> userVo.setOrgName(userOrg.getName()));
            //注入创建人名称
            createUserList.stream().filter(createUser -> createUser.getUserId().equals(userVo.getCreatedBy())).findAny().ifPresent(createUser -> userVo.setCreateByUserName(createUser.getName()));
        });
        BasePage<UserVo> voCondition = new BasePage<UserVo>();
        BeanUtils.copyProperties(condition, voCondition);
        voCondition.setList(userVoList);
        return new Result<>(voCondition);
    }

    /**
     * @Description: 用户详情
     * @Param: [userId]
     * @return: com.kingyea.mobilepolice.system.Result<com.kingyea.mobilepolice.user.bean.User>
     * @Author: cxc
     * @Date: 2018.04.10 16:09
     */
//    @PreAuthorize("hasAuthority('detail-user')")
    @PostMapping("/detail/{userId}")
    public Result<User> userDetail(@PathVariable("userId") String userId) throws Exception {
        ExceptionConditions.checkStringNotEmpty(userId, StateCode.NO_ARGUMENT_ERROR);
        return new Result<>(userService.getByUserId(userId));
    }

    /**
     * 系统接口,不能删
     *
     * @param user
     * @return java.security.Principal
     * @author Mr.Lin
     * @date 2018/4/8 19:13
     */
    @GetMapping()
    @NotResult
    public Principal user(Principal user) {
//        System.out.println(JSON.toJSONString(SecurityUtils.getCurrentUserUsername()));
//        System.out.println(JSON.toJSONString(SecurityUtils.getCurrentUser()));
//        System.out.println(SecurityUtils.isAdmin());
        return user;
    }

    @PostMapping()
    public Object user2(Map<String, Object> map) {
        System.out.println(JSON.toJSONString(map));
        return map;
    }

    @PostMapping("/test")
    public Object test(Map<String, Object> map) {
        System.out.println(JSON.toJSONString(SecurityUtils.getCurrentUserUsername()));
        System.out.println(JSON.toJSONString(SecurityUtils.getCurrentUser()));
        return map;
    }

    /**
     * @Description: 添加用户
     * @Param: [user]
     * @return: java.lang.Object
     * @Author: cxc
     * @Date: 2018.04.09 14:45
     */
    @PostMapping("/save")
    @PreAuthorize("hasAuthority('create-user')")
    public Object save(@RequestBody User user) throws Exception {
        ExceptionConditions.checkNotNull(user.getName(), StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkStringNotEmpty(user.getLoginId(), StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkStringNotEmpty(user.getPassword(), StateCode.NO_ARGUMENT_ERROR);
//        ExceptionConditions.checkStringNotEmpty(user.getOrgSerialNo(), StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkNotNull(organizationService.getBySerialNo(user.getOrgSerialNo()), StateCode.SERVER_DATA_MISSING_ERROR);
        ExceptionConditions.checkIsNull(userService.getByUserName(user.getLoginId()), StateCode.SERVER_DATA_DUPLICATE_ERROR);

        return userService.save(user);
    }

    /**
     * @Description: 修改用户
     * @Param: [user]
     * @return: com.kingyea.mobilepolice.user.bean.User
     * @Author: cxc
     * @Date: 2018.04.09 14:46
     */
    @PreAuthorize("hasAuthority('update-user')")
    @PostMapping("/update")
    public Object update(@RequestBody User user) throws Exception {
        ExceptionConditions.checkStringNotEmpty(user.getName(), StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkStringNotEmpty(user.getLoginId(), StateCode.NO_ARGUMENT_ERROR);
        User userOld = userService.getByUserName(SecurityUtils.getCurrentUser().getLoginId());
        if(!user.getLoginId().equals(userOld.getLoginId())){
            ExceptionConditions.checkIsNull(userService.getByUserName(user.getLoginId()), StateCode.SERVER_DATA_DUPLICATE_ERROR);
        }
        userOld.setMobile(user.getMobile());//暂不校验
        userOld.setEmail(user.getEmail());//暂不校验
        userOld.setName(user.getName());

        //需要更新的字段，自己扩展
        return userService.update(userOld);
    }

    /**
     * @Description: 修改个人信息
     * @Param: [user]
     * @return: com.kingyea.mobilepolice.user.bean.User
     * @Author: cxc
     * @Date: 2018.04.09 14:46
     */
    @PostMapping("/currUpdate")
    public Object currUpdate(@RequestBody User user) throws Exception {
        ExceptionConditions.checkStringNotEmpty(user.getName(), StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkIsNull(userService.getByUserName(user.getLoginId()), StateCode.SERVER_DATA_DUPLICATE_ERROR);
        user.setUserId(SecurityUtils.getCurrentUser().getUserId());
        return userService.update(user);
    }

    /**
     * @Description: 删除用户
     * @Param: [userId]
     * @return: java.lang.Boolean
     * @Author: cxc
     * @Date: 2018.04.09 14:46
     */
    @PreAuthorize("hasAuthority('delete-user')")
    @PostMapping("/del/{userId}")
    public Object del(@PathVariable("userId") String userId) throws Exception {
        return userService.deleteById(userId) > 0;
    }


    //获取当前登入用户信息
    @GetMapping("/getCurrentUserInfo")
    public Result<User> getCurrentUserInfo() {
        User user = SecurityUtils.getCurrentUser();
        System.out.println(JSON.toJSONString(user));
        return new Result<>(user);
    }

    /**
     * @Description: 需要在hander存储一份token
     * @param: [heander.token]
     * @return: com.kingyea.mobilepolice.system.Result<java.lang.Boolean>
     * @author: cxc
     * @Date: 2018/5/15
     */
    //获取当前登入用户信息
    @GetMapping("/toLogout")
    public Result<Boolean> toLogout() {
        return new Result<>(SecurityUtils.logout());
    }
}
